package dca.sistemascontrole.view.configuracao;

import dca.sistemascontrole.handler.HandlerMainFrame;
import dca.sistemascontrole.handler.HandlerPainelMalhaVisível;
import dca.sistemascontrole.malhadecontrole.MalhaFechada;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import javax.swing.JOptionPane;

/**
 *
 * @author Rafael
 */
public class PanelMalhaFechada extends javax.swing.JPanel implements ConfiguracaoProntaListener {

    private boolean mestreConfigurado;
    private boolean escravoConfigurado;
    private HandlerMainFrame handlerMainFrame;

    public PanelMalhaFechada(HandlerMainFrame handlerMainFrame) {
        initComponents();
        this.handlerMainFrame = handlerMainFrame;

        txtGama.setEnabled(false);
        txtTw.setEnabled(false);

        pnlControladorEscravo.desativar();
        pnlControladorEscravo.setConfiguracaoProntaListener(this);
        pnlControladorMestre.setConfiguracaoProntaListener(this);

        addHierarchyListener(new HierarchyListener() {
            public void hierarchyChanged(HierarchyEvent e) {
                hierarchyChangedEvent();
            }
        });
    }

    private void hierarchyChangedEvent() {
        boolean isExibidoAtual = isShowing();
        if (HandlerPainelMalhaVisível.getMalhaAtual() != HandlerPainelMalhaVisível.MALHA_FECHADA && isExibidoAtual) {
            buttonGroupControlador.clearSelection();
            handlerMainFrame.interromper();
            btnDefinir.setEnabled(false);

            HandlerPainelMalhaVisível.setMalhaAtual(HandlerPainelMalhaVisível.MALHA_FECHADA);
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroupControlador = new javax.swing.ButtonGroup();
        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel2 = new javax.swing.JPanel();
        btnDefinir = new dca.sistemascontrole.view.components.CustomButton();
        jPanel1 = new javax.swing.JPanel();
        chkFiltroAntiWindup = new javax.swing.JCheckBox();
        chkFiltroDerivativo = new javax.swing.JCheckBox();
        txtTw = new javax.swing.JTextField();
        txtGama = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jPanel7 = new javax.swing.JPanel();
        jLabel8 = new javax.swing.JLabel();
        txtSetpoint = new javax.swing.JTextField();
        pnlControladorEscravo = new dca.sistemascontrole.view.configuracao.PanelControlador();
        chkUsarControleCascata = new javax.swing.JCheckBox();
        pnlControladorMestre = new dca.sistemascontrole.view.configuracao.PanelControlador();

        setBackground(new java.awt.Color(255, 255, 255));
        setPreferredSize(new java.awt.Dimension(276, 716));
        setLayout(new java.awt.BorderLayout());

        jScrollPane1.setBorder(null);

        jPanel2.setBackground(new java.awt.Color(255, 255, 255));

        btnDefinir.setBackground(new java.awt.Color(250, 250, 250));
        btnDefinir.setText("Definir");
        btnDefinir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDefinirActionPerformed(evt);
            }
        });

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Filtros"));

        chkFiltroAntiWindup.setBackground(new java.awt.Color(255, 255, 255));
        chkFiltroAntiWindup.setText("Usar Anti Windup");
        chkFiltroAntiWindup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkFiltroAntiWindupActionPerformed(evt);
            }
        });

        chkFiltroDerivativo.setBackground(new java.awt.Color(255, 255, 255));
        chkFiltroDerivativo.setText("Usar Filtro Derivativo");
        chkFiltroDerivativo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkFiltroDerivativoActionPerformed(evt);
            }
        });

        jLabel1.setText("Gama:");

        jLabel7.setText("Tw:");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                        .addComponent(chkFiltroDerivativo)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtGama, javax.swing.GroupLayout.DEFAULT_SIZE, 66, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                        .addComponent(chkFiltroAntiWindup)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtTw)))
                .addContainerGap())
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {chkFiltroAntiWindup, chkFiltroDerivativo});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel7});

        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(chkFiltroAntiWindup)
                        .addComponent(txtTw, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.TRAILING))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(chkFiltroDerivativo)
                    .addComponent(jLabel1)
                    .addComponent(txtGama, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel1, jLabel7, txtTw});

        jPanel7.setBackground(new java.awt.Color(255, 255, 255));
        jPanel7.setBorder(javax.swing.BorderFactory.createTitledBorder("Configurar Setpoint"));

        jLabel8.setText("Setpoint:");

        javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
        jPanel7.setLayout(jPanel7Layout);
        jPanel7Layout.setHorizontalGroup(
            jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel7Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel8)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtSetpoint, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel7Layout.setVerticalGroup(
            jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel7Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(txtSetpoint))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlControladorEscravo.setBorder(javax.swing.BorderFactory.createTitledBorder("Escravo"));

        chkUsarControleCascata.setBackground(new java.awt.Color(255, 255, 255));
        chkUsarControleCascata.setText("Ativar Controle em Cascata");
        chkUsarControleCascata.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkUsarControleCascataActionPerformed(evt);
            }
        });

        pnlControladorMestre.setBorder(javax.swing.BorderFactory.createTitledBorder("Mestre"));

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(btnDefinir, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(pnlControladorEscravo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(chkUsarControleCascata)
                        .addComponent(pnlControladorMestre, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(19, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlControladorMestre, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(chkUsarControleCascata)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlControladorEscravo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(btnDefinir, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(21, Short.MAX_VALUE))
        );

        jScrollPane1.setViewportView(jPanel2);

        add(jScrollPane1, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    public void configuracaoStatusAtualizado(PanelControlador trigger) {
        if (trigger.equals(pnlControladorEscravo)) {
            escravoConfigurado = true;
        }
        
        if (trigger.equals(pnlControladorMestre)) {
            mestreConfigurado = true;
        }
        
        
        atualizarEstadoBotaoDefinir();
    }

    private void atualizarEstadoBotaoDefinir() {
        btnDefinir.setEnabled(mestreConfigurado && (escravoConfigurado || !chkUsarControleCascata.isSelected()));
    }

    private void btnDefinirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDefinirActionPerformed
        float kp = 0;
        float ki = 0;
        float kd = 0;
        float tw = 0;
        float setPoint;
        float gama = 0;
        int tipoControlador = pnlControladorMestre.getTipoControlador();

        String setpointSTR = txtSetpoint.getText().trim().replace(",", ".");
        if (!validarEntrada(setpointSTR)) {
            JOptionPane.showMessageDialog(this, "Setpoint invalido.");
            return;
        }
        setPoint = Float.parseFloat(setpointSTR);

        String kpSTR = pnlControladorMestre.getKP();
        if (!validarEntrada(kpSTR)) {
            JOptionPane.showMessageDialog(this, "Kp invalido.");
            return;
        }
        kp = Float.parseFloat(kpSTR);

        String kiSTR = pnlControladorMestre.getKI();
        if ((tipoControlador == MalhaFechada.PI || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && validarEntrada(kiSTR)) {
            ki = Float.parseFloat(kiSTR);
        } else if ((tipoControlador == MalhaFechada.PI || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && !validarEntrada(kiSTR)) {
            JOptionPane.showMessageDialog(this, "Ki ou Ti invalido.");
            return;
        }

        String kdSTR = pnlControladorMestre.getKD();
        if ((tipoControlador == MalhaFechada.PD || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && validarEntrada(kdSTR)) {
            kd = Float.parseFloat(kdSTR);
        } else if ((tipoControlador == MalhaFechada.PD || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && !validarEntrada(kdSTR)) {
            JOptionPane.showMessageDialog(this, "Kd ou Td invalido.");
            return;
        }

        String twSTR = txtTw.getText().trim().replace(",", ".");
        if (chkFiltroAntiWindup.isSelected() && validarEntrada(twSTR)) {
            tw = Float.parseFloat(twSTR);
        } else if (chkFiltroAntiWindup.isSelected() && !validarEntrada(twSTR)) {
            JOptionPane.showMessageDialog(this, "Tw invalido.");
            return;
        }

        String gamaSTR = txtGama.getText().trim().replace(",", ".");
        if (chkFiltroDerivativo.isSelected() && validarEntrada(gamaSTR)) {
            gama = Float.parseFloat(gamaSTR);
        } else if (chkFiltroDerivativo.isSelected() && !validarEntrada(gamaSTR)) {
            JOptionPane.showMessageDialog(this, "Gama invalido.");
            return;
        }

        boolean usarControleCascata = chkUsarControleCascata.isSelected();
        if (usarControleCascata) {
            definirControladorCascata(kp, ki, kd, tw, gama, setPoint);
        } else {
            definirControlador(kp, ki, kd, tw, gama, setPoint);
        }
    }//GEN-LAST:event_btnDefinirActionPerformed

    private void definirControlador(float kp, float ki, float kd, float tw, float gama, float setPoint) {
        int tipoControlador = pnlControladorMestre.getTipoControlador();

        handlerMainFrame.setMalhaDeControle(tipoControlador, setPoint, kp, ki, kd, tw, gama, chkFiltroDerivativo.isSelected(), chkFiltroAntiWindup.isSelected());
    }

    private void definirControladorCascata(float kpMestre, float kiMestre, float kdMestre, float tw, float gama, float setPoint) {
        float kp = 0;
        float ki = 0;
        float kd = 0;
        int tipoControlador = pnlControladorEscravo.getTipoControlador();

        String kpSTR = pnlControladorEscravo.getKP();
        if (!validarEntrada(kpSTR)) {
            JOptionPane.showMessageDialog(this, "Kp invalido.");
            return;
        }
        kp = Float.parseFloat(kpSTR);

        String kiSTR = pnlControladorEscravo.getKI();
        if ((tipoControlador == MalhaFechada.PI || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && validarEntrada(kiSTR)) {
            ki = Float.parseFloat(kiSTR);
        } else if ((tipoControlador == MalhaFechada.PI || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && !validarEntrada(kiSTR)) {
            JOptionPane.showMessageDialog(this, "Ki ou Ti invalido.");
            return;
        }

        String kdSTR = pnlControladorEscravo.getKD();
        if ((tipoControlador == MalhaFechada.PD || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && validarEntrada(kdSTR)) {
            kd = Float.parseFloat(kdSTR);
        } else if ((tipoControlador == MalhaFechada.PD || tipoControlador == MalhaFechada.PID || tipoControlador == MalhaFechada.PI_D) && !validarEntrada(kdSTR)) {
            JOptionPane.showMessageDialog(this, "Kd ou Td invalido.");
            return;
        }

        handlerMainFrame.setMalhaDeControleCascata(tipoControlador, setPoint, kpMestre, kiMestre, kdMestre, kp, ki, kd, tw, gama,
                chkFiltroDerivativo.isSelected(), chkFiltroAntiWindup.isSelected());
    }

    private void chkFiltroDerivativoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkFiltroDerivativoActionPerformed
        txtGama.setEnabled(chkFiltroDerivativo.isSelected());
        handlerMainFrame.usarFiltroDerivativo(chkFiltroDerivativo.isSelected());
    }//GEN-LAST:event_chkFiltroDerivativoActionPerformed

    private void chkFiltroAntiWindupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkFiltroAntiWindupActionPerformed
        txtTw.setEnabled(chkFiltroAntiWindup.isSelected());
        handlerMainFrame.usarFiltroAntiWindup(chkFiltroAntiWindup.isSelected());
    }//GEN-LAST:event_chkFiltroAntiWindupActionPerformed

    private void chkUsarControleCascataActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkUsarControleCascataActionPerformed
        boolean usarControleCascata = chkUsarControleCascata.isSelected();

        if (usarControleCascata) {
            pnlControladorEscravo.ativar();
        } else {
            pnlControladorEscravo.desativar();
        }

        atualizarEstadoBotaoDefinir();
    }//GEN-LAST:event_chkUsarControleCascataActionPerformed

    private boolean validarEntrada(String s) {
        try {
            Float.parseFloat(s);
        } catch (NumberFormatException ex) {
            return false;
        }

        return true;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private dca.sistemascontrole.view.components.CustomButton btnDefinir;
    private javax.swing.ButtonGroup buttonGroupControlador;
    private javax.swing.JCheckBox chkFiltroAntiWindup;
    private javax.swing.JCheckBox chkFiltroDerivativo;
    private javax.swing.JCheckBox chkUsarControleCascata;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JScrollPane jScrollPane1;
    private dca.sistemascontrole.view.configuracao.PanelControlador pnlControladorEscravo;
    private dca.sistemascontrole.view.configuracao.PanelControlador pnlControladorMestre;
    private javax.swing.JTextField txtGama;
    private javax.swing.JTextField txtSetpoint;
    private javax.swing.JTextField txtTw;
    // End of variables declaration//GEN-END:variables
}
